package com.sunyy.codegenerator.service.impl;

import com.sunyy.codegenerator.common.MyException;
import com.sunyy.codegenerator.service.CosService;
import io.minio.*;
import io.minio.errors.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * @author sunyy
 * @since 2025/7/19
 */
@Slf4j
@Service
@ConditionalOnBean(name = "minioClient")
public class MinIOCosServiceImpl implements CosService {

    @Resource(name = "minioClient")
    private MinioClient minioClient;

    @Override
    public void createBucket(String bucketName) {
        try {
            minioClient.makeBucket(
                    MakeBucketArgs.builder()
                            .bucket(bucketName)
                            .build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                 XmlParserException e) {
            log.error(e.getMessage(), e);
            throw new MyException("创建bucket失败!!");
        }
    }

    @Override
    public void uploadFile(String bucketName, String folder, byte[] fileBytes) {
        PutObjectArgs build = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(folder)
                .stream(new ByteArrayInputStream(fileBytes), fileBytes.length, -1)
                .build();
        try {
            minioClient.putObject(build);
        } catch (Throwable e) {
            log.error(e.getMessage(), e);
            throw new MyException("上传文件失败");
        }
    }

    @Override
    public void uploadFile(String bucketName, String folder, InputStream is) {
        PutObjectArgs build = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(folder)
                .stream(is, -1, 10485760)
                .build();
        try {
            minioClient.putObject(build);
        } catch (ServerException | InsufficientDataException | ErrorResponseException | IOException |
                 NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException | XmlParserException |
                 InternalException e) {
            log.error(e.getMessage(), e);
            throw new MyException("上传文件失败!!");
        }
    }

    @Override
    public void uploadFile(String bucketName, String folder, File file) {
        try (FileInputStream fis = new FileInputStream(file);) {
            uploadFile(bucketName, folder, fis);
        } catch (FileNotFoundException e) {
            log.error(e.getMessage(), e);
            throw new MyException("文件不存在!!");
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new MyException("文件上传失败!!");
        }
    }

    @Override
    public void uploadFile(String bucketName, String folder, Path filePath) {
        try {
            uploadFile(bucketName, folder, Files.newInputStream(filePath));
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new MyException("文件上传失败!!");
        }
    }

    @Override
    public void uploadFile(String bucketName, String folder, String filePath) {
        uploadFile(bucketName, folder, Paths.get(filePath));
    }

    @Override
    public byte[] getFileBytes(String bucketName, String folder) {
        try (InputStream is = getFileInputStream(bucketName, folder)) {
            return is.readAllBytes();
        } catch (IOException e) {
            log.error(e.getMessage(), e);
            throw new MyException("获取文件失败!!");
        }
    }

    @Override
    public InputStream getFileInputStream(String bucketName, String folder) {
        try {
            return minioClient.getObject(
                    GetObjectArgs.builder()
                            .bucket(bucketName)
                            .object(folder)
                            .build());
        } catch (ServerException | NoSuchAlgorithmException | InvalidKeyException | InvalidResponseException |
                 XmlParserException | InternalException | InsufficientDataException | ErrorResponseException |
                 IOException e) {
            log.error(e.getMessage(), e);
            throw new MyException("获取文件失败!!");
        }
    }

    @Override
    public void deleteFile(String bucketName, String folder) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder()
                    .bucket(bucketName)
                    .object(folder)
                    .build());
        } catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidKeyException |
                 InvalidResponseException | IOException | NoSuchAlgorithmException | ServerException |
                 XmlParserException e) {
            log.error(e.getMessage(), e);
        }
    }
}
